
import { gameConfigHandle } from "core/config/gameConfig"
import utils from "core/utils/utils"
import { EffectModel, FighterAttriModel, FighterModel } from "core/model/fighterModel"
import { FighterSkillModel } from "core/model/skillModel"
import { BuffType } from "core/typeDefine/typeDefine"
import { BuffModel } from "core/model/buffModel"



class FighterHandle {
    perList1 = ["strPer", "conPer", "agilePer", "spiritPer", "willPer", "maxHpPer", "maxMpPer", "attackSpeedPer", "attackPer", "pAttackPer", "lAttackPer",
        "defPer", "pDefPer", "lDefPer", "puncturePer", "pPuncturePer", "lPuncturePer", "hitPer", "dodgePer", "critPer", "scritPer", "antiCritPer",
        "antiSCritPer", "speedPer", "recoverHpPer"
    ]
    perList2 = ["strReducePer", "conReducePer", "agileReducePer", "spiritReducePer", "willReducePer", "maxHpReducePer", "maxMpReducePer", "attackSpeedReducePer", "attackReducePer", "pAttackReducePer", "lAttackReducePer",
        "defReducePer", "pDefReducePer", "lDefReducePer", "punctureReducePer", "pPunctureReducePer", "lPunctureReducePer", "hitReducePer", "dodgeReducePer", "critReducePer", "scritReducePer", "antiCritReducePer",
        "antiSCritReducePer", "speedReducePer"
    ]
    perList3 = ['maxHpUpPer', 'attackUpPer', 'defUpPer', 'speedUpPer']
    baseList = ['maxHp', 'attack', 'def', 'speed']
    calcSkillsAttris(fighter: FighterModel) {
        let skills: FighterSkillModel[] = []
        if (fighter.skills) {
            skills = skills.concat(fighter.skills)
        }
        for (let i = 0; i < skills.length; i++) {
            let skill = skills[i]
            if (!skill) {
                continue
            }
            let skillID = skills[i].tid
            let skillLvl = (skills[i].lvl || 1)
            let skillConfig = gameConfigHandle.configByID[skillID]
            let starLvl = Math.floor(skillLvl / 10)
            skill.starLvl = starLvl

            skill.aSkills.forEach(item => {
                let askillID = item[0]
                let askillLvl = item[1] || 1
                let askillConfig = gameConfigHandle.configByID[askillID]
                if (askillConfig.attris) {
                    utils.entries(skillConfig.attris).forEach(attri => {
                        let attriName = attri[0]
                        let values: any = attri[1]
                        fighter.attris[attriName] += utils.getIncValues(values, askillLvl)
                    })
                }
            })

            if (skillConfig.attris) {
                utils.entries(skillConfig.attris).forEach(attri => {
                    let attriName = attri[0]
                    let values: any = attri[1]
                    fighter.attris[attriName] += utils.getIncValues(values, skillLvl)
                })
            }
            if (skillConfig.statusHurtPer) {
                utils.entries(skillConfig.statusHurtPer).forEach(item => {
                    let id = item[0]
                    let values = item[1] as any
                    let value = utils.getIncValues(values, skillLvl)
                    if (!fighter.statusHurtPer[id]) {
                        fighter.statusHurtPer[id] = 0
                    }
                    fighter.statusHurtPer[id] += value
                })
            }

        }
    }



    calcSkills(fighter: FighterModel, battleHandle?: any) {
        let skills: FighterSkillModel[] = []
        if (fighter.skills) {
            skills = skills.concat(fighter.skills)
        }
        let effectID = 1
        for (let i = 0; i < skills.length; i++) {
            let skill = skills[i]
            if (!skill) {
                continue
            }
            let skillID = skills[i].tid
            let skillLvl = (skills[i].lvl || 1)
            let skillConfig = gameConfigHandle.configByID[skillID]
            let starLvl = Math.floor(skillLvl / 10)
            skill.starLvl = starLvl
            skill.index = i
            if (skillConfig.triggers) {
                skillConfig.triggers.forEach(triggerItem => {
                    let effect = new EffectModel({
                        trigger: fighter,
                        id: effectID++,
                        type: triggerItem.triggerType,
                        skillID: skillID,
                        skillLvl: skillLvl,
                        skillIndex: i,
                        eSkillID: skillID,
                        eSkillLvl: skillLvl,
                        data: JSON.parse(JSON.stringify(triggerItem))
                    })
                    if (triggerItem.triggerType < 50) {
                        if (!fighter.effects[triggerItem.triggerType]) {
                            fighter.effects[triggerItem.triggerType] = []
                        }
                        fighter.effects[triggerItem.triggerType].push(effect)
                    } else {
                        if (battleHandle) {
                            if (!battleHandle.otherEffects[triggerItem.triggerType]) {
                                battleHandle.otherEffects[triggerItem.triggerType] = []
                            }
                            battleHandle.otherEffects[triggerItem.triggerType].push(effect)
                        }

                    }
                })
            }

            skill.aSkills.forEach(item => {
                let askillID = item[0]
                let askillLvl = item[1] || 1
                let askillConfig = gameConfigHandle.configByID[askillID]
                if (askillConfig.triggers) {
                    askillConfig.triggers.forEach(triggerItem => {
                        if (triggerItem.triggerType < 50) {
                            let trigger = new EffectModel({
                                type: triggerItem.triggerType,
                                skillID: skillID,
                                skillLvl: askillLvl,
                                eSkillID: askillID,
                                eSkillLvl: askillLvl,
                                data: JSON.parse(JSON.stringify(triggerItem))
                            })
                            if (!fighter.effects[triggerItem.triggerType]) {
                                fighter.effects[triggerItem.triggerType] = []
                            }
                            fighter.effects[triggerItem.triggerType].push(trigger)
                        }

                    })
                }
                if (askillConfig.skillAttris) {
                    utils.entries(askillConfig.skillAttris).forEach(attri => {
                        let attriName = attri[0]
                        let values: any = attri[1]
                        skill[attriName] += utils.getIncValues(values, askillLvl)
                    })
                }
                if (askillConfig.setSkillAttris) {
                    utils.entries(askillConfig.setSkillAttris).forEach(attri => {
                        let attriName = attri[0]
                        let value: any = attri[1]
                        skill[attriName] = value
                    })
                }
            })
            if (skillConfig.setNormalAttack) {
                fighter.normalAttackData = utils.assign({}, skillConfig.setNormalAttack)

            }
            if (skillConfig.setAttris) {
                utils.entries(skillConfig.setAttris).forEach(attri => {
                    let attriName = attri[0]
                    let value = attri[1]
                    fighter[attriName] = value
                })
            }

            if (skillConfig.cd) {
                skill.cd = skillConfig.cd - skill.cd
                if (fighter.skillCds[skillID]) {
                    skill.cd = skill.cd - fighter.skillCds[skillID]
                }
                if (skill.cdPer) {
                    skill.cd = skill.cd * (100 - skill.cdPer) / 100
                }
                if (fighter.skillCdPers[skillID]) {
                    skill.cd = skill.cd * (100 - fighter.skillCdPers[skillID]) / 100
                }
            }
            if (skill.reduceMpPer) {
                skill.mp = Math.floor(skill.mp * (100 - skill.reduceMpPer) / 100)
            }
        }
    }

    calcBaseAttrisFighterAttri(fighter: FighterModel) {
        //汇总

        this.calcAttriPer(fighter.attris)

        this.perList1.forEach(item => {
            fighter.attris[item] = 0
        })
        this.perList2.forEach(item => {
            fighter.attris[item] = 0
        })
        this.perList3.forEach(item => {
            fighter.attris[item] = 0
        })
        fighter.attris['mainAttriUpPer'] = 0
    }
    calcBattleFighterAttri(fighter: FighterModel, aureoles?: BuffModel[]) {
        let hp = 0, mp = 0, anger = 0, shield = 0;
        if (fighter.battleAttris) {
            hp = fighter.battleAttris.hp
            mp = fighter.battleAttris.mp
            anger = fighter.battleAttris.anger
            shield = fighter.battleAttris.shield
        }
        if (!fighter.isGetStartShield) {
            let startShield = Math.floor(fighter.attris.maxHp * fighter.attris.startShieldPer / 100)
            shield = startShield
            fighter.isGetStartShield = true
        }

        let battleAttri: FighterAttriModel
        if (fighter.attrisStr) {
            battleAttri = new FighterAttriModel(JSON.parse(fighter.attrisStr))
        } else {
            battleAttri = new FighterAttriModel(fighter.attris)
        }
        new FighterAttriModel(fighter.attris)

        fighter.status = {}
        //buff
        for (let buff of fighter.buffs) {
            if (buff.stack > 0 || buff.round > 0) {
                let buffConfig = gameConfigHandle.configByID[buff.tid]
                let buffLvl = buff.lvl
                if (buffConfig.attris) {
                    utils.entries(buffConfig.attris).map((item) => {
                        let attriName = item[0]
                        let attriValue: any = item[1]
                        let value = utils.getIncValues(attriValue, buffLvl - 1)
                        battleAttri[attriName] += value
                    })
                }
                if (buffConfig.stackAttris && buff.stack && buff.stack >= 1) {
                    utils.entries(buffConfig.stackAttris).map((item) => {
                        let attriName = item[0]
                        let attriValue: any = item[1]
                        let value = 0
                        value += utils.getIncValues(attriValue, buffLvl - 1) * (buff.stack || 1)
                        battleAttri[attriName] += value
                    })
                }
                if (buffConfig.buffType !== BuffType.Attri) {
                    if (buffConfig.buffType == BuffType.YiShang || buffConfig.buffType == BuffType.Poison) {
                        fighter.status[buffConfig.buffType] = buff.stack
                    } else {
                        fighter.status[buffConfig.buffType] = true
                    }
                }
            }
            if (buff.attris) {
                utils.entries(buff.attris).map((item) => {
                    let attriName = item[0]
                    let value: any = item[1]
                    battleAttri[attriName] += value * (buff.stack || 1)
                })
            }
        }
        if (aureoles) {
            for (let buff of aureoles) {
                let buffConfig = gameConfigHandle.configByID[buff.tid]
                let buffLvl = buff.lvl
                if (buffConfig.attris && buff.teamID == fighter.teamID) {
                    utils.entries(buffConfig.attris).map((item) => {
                        let attriName = item[0]
                        let attriValues: any = item[1]
                        let value = 0
                        value += utils.getIncValues(attriValues, buffLvl - 1)
                        battleAttri[attriName] += value
                    })
                }
            }
        }
        for (let tempAttri of fighter.tempAttris) {
            if (tempAttri) {
                battleAttri[tempAttri.name] += tempAttri.value
            }
        }

        //汇总
        this.calcAttriPer(battleAttri)
        fighter.battleAttris = battleAttri
        fighter.battleAttris.hp = hp
        fighter.battleAttris.mp = mp
        fighter.battleAttris.anger = anger// + (fighter.battleAttris.startMp || 0)
        // let startShield = Math.floor(fighter.battleAttris.hp * fighter.battleAttris.startShieldPer / 100)
        // console.log('startShield',startShield)
        fighter.battleAttris.shield = shield
        this.caclPower(fighter)
    }



    //汇总
    calcAttriPer(battleAttri: FighterAttriModel) {
        //加强属性
        battleAttri.maxHpUpPer += battleAttri.mainAttriUpPer
        battleAttri.attackUpPer += battleAttri.mainAttriUpPer
        battleAttri.defUpPer += battleAttri.mainAttriUpPer
        battleAttri.speedUpPer += battleAttri.mainAttriUpPer
        //百分比属性
        battleAttri.maxHp = Math.floor(battleAttri.maxHp * (1 + battleAttri.maxHpPer / 100) * (1 + battleAttri.maxHpUpPer / 100))
        battleAttri.attack = Math.floor(battleAttri.attack * (1 + battleAttri.attackPer / 100) * (1 + battleAttri.attackUpPer / 100) * (1 - battleAttri.attackReducePer / 100))
        battleAttri.def = Math.floor(battleAttri.def * (1 + battleAttri.defPer / 100) * (1 + battleAttri.defUpPer / 100) * (1 - battleAttri.defReducePer / 100))
        battleAttri.speed = Math.floor(battleAttri.speed * (1 + battleAttri.speedPer / 100) * (1 + battleAttri.speedUpPer / 100) * (1 - battleAttri.speedReducePer / 100))

        battleAttri.attackSpeed = Math.floor(battleAttri.attackSpeed * (1 + battleAttri.attackSpeedPer / 100) * (1 - battleAttri.attackSpeedReducePer / 100))
        battleAttri.maxMp = Math.floor(battleAttri.maxMp * (1 + battleAttri.maxMpPer / 100))
        battleAttri.crit = Math.floor(battleAttri.crit * (1 + battleAttri.critPer / 100) * (1 - battleAttri.critReducePer / 100))
        battleAttri.scrit = Math.floor(battleAttri.scrit * (1 + battleAttri.scritPer / 100) * (1 - battleAttri.scritReducePer / 100))
        battleAttri.hit = Math.floor(battleAttri.hit * (1 + battleAttri.hitPer / 100) * (1 - battleAttri.hitReducePer / 100))
        battleAttri.dodge = Math.floor(battleAttri.dodge * (1 + battleAttri.dodgePer / 100) * (1 - battleAttri.dodgeReducePer / 100))
        battleAttri.recoverHp = Math.floor(battleAttri.recoverHp * (1 + battleAttri.recoverHpPer / 100))

    }

    caclPower(fighter: FighterModel) {
        let power = 0
        let powerConfig = gameConfigHandle.gameConfig.partner.partnerPower
        let powerPerConfig = gameConfigHandle.gameConfig.partner.partnerPowerPer
        let per = 0
        utils.entries(powerConfig).forEach(item => {
            let name = item[0]
            let value = item[1]
            power += (fighter.battleAttris[name] || 0) * value
        })
        utils.entries(powerPerConfig).forEach(item => {
            let name = item[0]
            let value = item[1]
            value = (fighter.battleAttris[name] || 0) * value
            if (value > 50) {
                value = 50
            }
            per += value
        })

        power = Math.floor(power * (1 + per / 100))
        fighter.power = power
        return power
    }

}


let fighterHandle = new FighterHandle()

export default fighterHandle
